<!DOCTYPE html>
<html lang="en">
	<head>
		<title>三维重建</title>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<link type="text/css" rel="stylesheet" href="../static/main.css">
		<style>
			#inset {
				width: 150px;
				height: 150px;
				background-color: transparent; /* or transparent; will show through only if renderer alpha: true */
				border: none; /* or none; */
				margin: 0;
				padding: 0px;
				position: absolute;
				left: 20px;
				bottom: 20px;
				z-index: 100;
			}
		</style>
	</head>
	<body>
		<div id="info">
			CT影像三维重建
		</div>
		<div id="inset"></div>
		<script type="module">
			import * as THREE from '../static/build/three.module.js';
			import Stats from '../static/jsm/libs/stats.module.js';
			import { GUI } from '../static/jsm/libs/dat.gui.module.js';
			import { TrackballControls } from '../static/jsm/controls/TrackballControls.js';
			import { NRRDLoader } from '../static/jsm/loaders/NRRDLoader.js';

			import { STLLoader} from "../static/jsm/loaders/STLLoader.js";
			var container,
				stats,
				camera,
				controls,
				scene,
				renderer,
				container2,
				renderer2,
				camera2,
				axes2,
				scene2,
				raycaster;
			var mouse = new THREE.Vector2(), INTERSECTED;


			init();
			animate();
			function init() {
				camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.01, 1e10 );
				camera.position.z = 300;
				scene = new THREE.Scene();
				scene.add( camera );

				// light
				var hemiLight = new THREE.HemisphereLight( 0xffffff, 0x000000 , 1 );
				scene.add( hemiLight );
				var dirLight = new THREE.DirectionalLight( 0xffffff, 0.5 );
				dirLight.position.set( 200, 200, 200 );
				scene.add( dirLight );

				var loader = new NRRDLoader();
				loader.load( {{ ddd|safe }}, function ( volume ) {
					var geometry,
						material,
						sliceZ,
						sliceY,
						sliceX;
					//box helper to see the extend of the volume
					var geometry = new THREE.BoxBufferGeometry( volume.xLength, volume.yLength, volume.zLength );
					var material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } );
					var cube = new THREE.Mesh( geometry, material );
					cube.visible = false;
					var box = new THREE.BoxHelper( cube );
					console.log(box.position);
					scene.add( box );
					box.applyMatrix4( volume.matrix );
					scene.add( cube );
					console.log(cube.position);
					//z plane
					sliceZ = volume.extractSlice( 'z', Math.floor( volume.RASDimensions[ 2 ] / 4 ) );
					scene.add( sliceZ.mesh );
					//y plane
					sliceY = volume.extractSlice( 'y', Math.floor( volume.RASDimensions[ 1 ] / 2 ) );
					scene.add( sliceY.mesh );
					//x plane
					sliceX = volume.extractSlice( 'x', Math.floor( volume.RASDimensions[ 0 ] / 2 ) );
					scene.add( sliceX.mesh );
					var slicer = gui.addFolder("切片显示");
					var index = gui.addFolder("切片深度");
					var threshold = gui.addFolder("CT阈值调整");
					var window = gui.addFolder("窗位调整");
					var slicerControl = {
						Xvisible: true,
						Yvisible: true,
						Zvisible: true
					};
					slicer.add( slicerControl, "Xvisible" ).name( "矢状面" ).onChange( function () {
						sliceX.mesh.visible = slicerControl.Xvisible;
						renderer.render( scene, camera );
					} );
					slicer.add( slicerControl, "Yvisible" ).name( "冠状面" ).onChange( function () {
						sliceY.mesh.visible = slicerControl.Yvisible;
						renderer.render( scene, camera );
					} );
					slicer.add( slicerControl, "Zvisible" ).name( "横断面" ).onChange( function () {
						sliceZ.mesh.visible = slicerControl.Zvisible;
						renderer.render( scene, camera );
					} );
					index.add( sliceX, "index", 0, volume.RASDimensions[ 0 ], 1 ).name( "矢状面序列" ).onChange( function () {
						sliceX.repaint.call( sliceX );
					} );
					index.add( sliceY, "index", 0, volume.RASDimensions[ 1 ], 1 ).name( "冠状面序列" ).onChange( function () {
						sliceY.repaint.call( sliceY );
					} );
					index.add( sliceZ, "index", 0, volume.RASDimensions[ 2 ], 1 ).name( "横断面序列" ).onChange( function () {
						sliceZ.repaint.call( sliceZ );
					} );
					threshold.add( volume, "lowerThreshold", volume.min, volume.max, 1 ).name( "最低CT值" ).onChange( function () {
						volume.repaintAllSlices();
					} );
					threshold.add( volume, "upperThreshold", volume.min, volume.max, 1 ).name( "最高CT值" ).onChange( function () {
						volume.repaintAllSlices();
					} );
					window.add( volume, "windowLow", volume.min, volume.max, 1 ).name( "低位" ).onChange( function () {
						volume.repaintAllSlices();
					} );
					window.add( volume, "windowHigh", volume.min, volume.max, 1 ).name( "高位" ).onChange( function () {
						volume.repaintAllSlices();
					} );


				} );

				var amaterial = new THREE.MeshLambertMaterial( { wireframe: false, morphTargets: false, side: THREE.DoubleSide, color: 0xff0000 } );
				var bmaterial = new THREE.MeshLambertMaterial( { wireframe: false, morphTargets: false, side: THREE.DoubleSide, color: 0x00ff00 } );
				var cmaterial = new THREE.MeshLambertMaterial( { wireframe: false, morphTargets: false, side: THREE.DoubleSide, color: 0x0000ff } );

				var loader1 = new STLLoader();
				loader1.load( {{ aaa|safe }}, function ( geometry ) {

					//geometry.computeVertexNormals();

					var mesh1 = new THREE.Mesh( geometry, amaterial );
					var center = new THREE.Vector3();
					mesh1.geometry.computeBoundingBox();
					mesh1.geometry.boundingBox.getCenter(center);
					let x = center.x;
					let y =  center.y;
					let z =  center.z;
					console.log(center);
					mesh1.geometry.center();
					mesh1.rotateZ(Math.PI);
					scene.add( mesh1 );
					var organ = gui.addFolder("器官显示");
					var visibilityControl = {
						visible: true
					};
					organ.add( visibilityControl, "visible" ).name( "神经根" ).onChange( function () {
						mesh1.visible = visibilityControl.visible;
						renderer.render( scene, camera );
					} );

					loader1.load( {{ bbb|safe }}, function ( geometry ) {
					//geometry.computeVertexNormals();
					var mesh2 = new THREE.Mesh( geometry, bmaterial );
					mesh2.geometry.translate(-x,-y,-z);
					mesh2.rotateZ(Math.PI);
					scene.add( mesh2 );
					var visibilityControl = {
						visible: true
					};
					organ.add( visibilityControl, "visible" ).name( "椎间盘" ).onChange( function () {
						mesh2.visible = visibilityControl.visible;
						renderer.render( scene, camera );
					} );
				} );
					loader1.load( {{ ccc|safe }}, function ( geometry ) {
					//geometry.computeVertexNormals();
					var mesh3 = new THREE.Mesh( geometry, cmaterial );
					mesh3.geometry.translate(-x,-y,-z);
					mesh3.rotateZ(Math.PI);
					scene.add( mesh3 );
					var visibilityControl = {
						visible: true
					};
					organ.add( visibilityControl, "visible" ).name( "硬膜囊" ).onChange( function () {
						mesh3.visible = visibilityControl.visible;
						renderer.render( scene, camera );
					} );

				} );

				} );
				raycaster = new THREE.Raycaster();
				// renderer

				renderer = new THREE.WebGLRenderer( { alpha: true } );
				renderer.setPixelRatio( window.devicePixelRatio );
				renderer.setSize( window.innerWidth, window.innerHeight );

				container = document.createElement( 'div' );
				document.body.appendChild( container );
				container.appendChild( renderer.domElement );

				controls = new TrackballControls( camera, renderer.domElement );
				controls.minDistance = 100;
				controls.maxDistance = 500;
				controls.rotateSpeed = 5.0;
				controls.zoomSpeed = 5;
				controls.panSpeed = 2;

				stats = new Stats();
				container.appendChild( stats.dom );

				document.addEventListener( 'mousemove', onDocumentMouseMove, false );

				var gui = new GUI();

				setupInset();

				window.addEventListener( 'resize', onWindowResize, false );


			}

			function onWindowResize() {

				camera.aspect = window.innerWidth / window.innerHeight;
				camera.updateProjectionMatrix();

				renderer.setSize( window.innerWidth, window.innerHeight );

				controls.handleResize();

			}

			function onDocumentMouseMove( event ) {

				event.preventDefault();

				mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
				mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;

			}

			function animate() {

				requestAnimationFrame( animate );

				controls.update();
				//copy position of the camera into inset
				camera2.position.copy( camera.position );
				camera2.position.sub( controls.target );
				camera2.position.setLength( 300 );
				camera2.lookAt( scene2.position );
				renderer.render( scene, camera );
				renderer2.render( scene2, camera2 );
				stats.update();
			}

			function setupInset() {
				var insetWidth = 150,
					insetHeight = 150;
				container2 = document.getElementById( 'inset' );
				container2.width = insetWidth;
				container2.height = insetHeight;
				// renderer
				renderer2 = new THREE.WebGLRenderer( { alpha: true } );
				renderer2.setClearColor( 0x000000, 0 );
				renderer2.setSize( insetWidth, insetHeight );
				container2.appendChild( renderer2.domElement );
				// scene
				scene2 = new THREE.Scene();
				// camera
				camera2 = new THREE.PerspectiveCamera( 50, insetWidth / insetHeight, 1, 1000 );
				camera2.up = camera.up; // ****
				// axeshelper
				axes2 = new THREE.AxesHelper( 100 );
				scene2.add( axes2 );
			}
		</script>
	</body>
</html>
